package org.codingq92.project.bio_chat.client;

import org.codingq92.project.bio_chat.util.Constants;

import javax.swing.*;
import java.awt.*;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

/**
 * 登录窗口类
 * 使用 Swing 实现登录界面
 */
public class LoginFrame extends JFrame {
    // 用户名输入框
    private final JTextField nameField;
    // IP 输入框
    private final JTextField ipField;
    // 消息通信
    private static Socket socket;
    // 聊天窗口
    private static ChatFrame chatFrame;
    // 在线人员名单
    private static java.util.List<String> onlineUsers = new ArrayList<>();

    public LoginFrame() {
        // 设置窗口标题
        super("登录");
        // 设置窗口关闭操作
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 设置窗口大小
        setSize(300, 200);
        // 设置窗口居中显示
        setLocationRelativeTo(null);
        // 创建面板
        JPanel panel = new JPanel();
        // 设置布局为 GridBagLayout（更灵活的布局）
        panel.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(5, 5, 5, 5); // 设置组件间距
        gbc.fill = GridBagConstraints.HORIZONTAL; // 组件水平填充
        // 添加 IP 标签和输入框
        gbc.gridx = 0;
        gbc.gridy = 0;
        panel.add(new JLabel("IP:"), gbc);
        gbc.gridx = 1;
        gbc.gridy = 0;
        ipField = new JTextField(Constants.SERVER_IP, 15); // 默认 IP
        panel.add(ipField, gbc);
        // 添加用户名标签和输入框
        gbc.gridx = 0;
        gbc.gridy = 1;
        panel.add(new JLabel("姓名:"), gbc);
        gbc.gridx = 1;
        gbc.gridy = 1;
        nameField = new JTextField(15); // 用户名输入框
        panel.add(nameField, gbc);
        // 添加按钮面板
        JPanel buttonPanel = new JPanel();
        JButton loginButton = new JButton("登录"); // 登录按钮
        JButton cancelButton = new JButton("取消"); // 取消按钮
        // 登录按钮事件监听
        loginButton.addActionListener(e -> {
            String name = nameField.getText(); // 获取用户名
            String ip = ipField.getText();       // 获取 IP
            if (!name.isEmpty()) { // 用户名不为空时打开聊天窗口
                loginAction(ip, name);
            } else {
                JOptionPane.showMessageDialog(LoginFrame.this, "请输入姓名！");
            }
        });
        // 取消按钮事件监听
        cancelButton.addActionListener(e -> dispose());
        buttonPanel.add(loginButton);
        buttonPanel.add(cancelButton);
        // 添加按钮面板到主面板
        gbc.gridx = 0;
        gbc.gridy = 2;
        gbc.gridwidth = 2; // 按钮面板跨两列
        panel.add(buttonPanel, gbc);
        // 将面板添加到窗口
        getContentPane().add(panel);
        // 设置窗口可见
        setVisible(true);
    }


    /**
     * 发送群聊消息
     *
     * @param message 消息
     */
    public static void sendGroupMsg(String message) {
        try {
            OutputStream outputStream = socket.getOutputStream();
            DataOutputStream dos = new DataOutputStream(outputStream);
            dos.writeInt(Constants.GROUP_MSG);
            dos.writeUTF(message);
            dos.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 发送私聊消息
     *
     * @param username 私聊的用户名
     * @param message  私聊的消息
     */
    public static void sendPrivateMsg(String username, String message) {
        try {
            OutputStream outputStream = socket.getOutputStream();
            DataOutputStream dos = new DataOutputStream(outputStream);
            dos.writeInt(Constants.PRIVATE_MSG);
            dos.writeUTF(username);
            dos.writeUTF(message);
            dos.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 登录操作
     *
     * @param ip   ip
     * @param name 用户名
     */
    private void loginAction(String ip, String name) {
        // 需要连接上server端
        try {
            // 打开聊天窗口
            chatFrame = new ChatFrame(name, onlineUsers);
            // 通信
            socket = new Socket(ip, Constants.SERVER_PORT);
            // 需要读取Server发送回来的所有在线人员名单
            new Thread(LoginFrame::handlerGroupMsg).start();
            // 将自己的名称发送给server端
            OutputStream os = socket.getOutputStream();
            DataOutputStream dos = new DataOutputStream(os);
            dos.writeInt(Constants.LOGIN);
            dos.writeUTF(name);
            dos.flush();
            // 关闭当前登录窗口
            dispose();
            System.out.println("[" + name + "]登录成功! " + Constants.getTime());
        } catch (Exception e1) {
            JOptionPane.showMessageDialog(LoginFrame.this, "服务器连接失败！" + e1.getMessage());
            dispose();
        }
    }

    /**
     * 处理Server端反馈的消息
     */
    private static void handlerGroupMsg() {
        try {
            InputStream is = socket.getInputStream();
            DataInputStream dis = new DataInputStream(is);
            while (true) {
                int flag = dis.readInt();
                if (flag == Constants.LOGIN) {
                    onlineUsers = new ArrayList<>();
                    String onlineUserStr = dis.readUTF();
                    String[] split = onlineUserStr.split(Constants.SPLIT);
                    onlineUsers.addAll(List.of(split));
                    System.out.println("更新最新在线人员名单：" + onlineUsers + " " + Constants.getTime());
                    chatFrame.updateUserList(onlineUsers);
                } else if (flag == Constants.GROUP_MSG) {
                    String message = dis.readUTF();
                    System.out.println("收到群聊消息：" + message + " " + Constants.getTime());
                    chatFrame.appendMessage("", message);
                } else if (flag == Constants.PRIVATE_MSG) {
                    String message = dis.readUTF();
                    System.out.println("收到私聊消息：" + message + " " + Constants.getTime());
                    chatFrame.appendMessage("", message);
                }
            }
        } catch (Exception e2) {
            e2.printStackTrace();
        }
    }

    public static void main(String[] args) {
        // 确保 Swing 组件在事件调度线程中运行
        SwingUtilities.invokeLater(LoginFrame::new);
    }
}